# encoding:utf-8
import time

import os
import re
from pexpect import EOF
from pexpect import TIMEOUT
from pexpect import spawn

from app.modules.apps.container import ContainerApp
# 抽象发布到tomcat下的war包,以及其专用tomcat容器的对象.
from app.modules.common.utils import FileUtil
from config import BeetleConfig


class TomcatApp(ContainerApp):
    def __init__(self, app_id, app_name, zone_home_path, zone_alias, port,
                 nas_app_package_path = '',
                 sub_path = '',
                 tomcat_template_home = '/usr/local/soft/tomcat-7',
                 mem_level = 1,
                 container_home = '',
                 app_config_home_path = None,
                 war_exposed_name = '',
                 war_config_path = '/WEB-INF/classes',
                 timezone = ''):

        if container_home == '':
            container_home = zone_home_path + '/tomcat_' + app_name

        super(TomcatApp, self).__init__(app_id = app_id, app_name = app_name,
                                        zone_home_path = zone_home_path,
                                        zone_alias = zone_alias, port = port,
                                        nas_app_package_path = nas_app_package_path,
                                        container_home = container_home,
                                        sub_path = sub_path)

        self._tomcat_template_home = tomcat_template_home

        self._app_home_path = self._container_home + '/webapps'

        if mem_level == 1:
            self._java_opts = r'declare -x JAVA_OPTS="-Xms384m -Xmx384m -XX:PermSize=64m' \
                              r' -XX:MaxPermSize=256m -XX:-UseGCOverheadLimit"'
        elif mem_level == 2:
            self._java_opts = r'declare -x JAVA_OPTS="-Xms512m -Xmx512m -XX:PermSize=64m' \
                              r' -XX:MaxPermSize=256m -XX:-UseGCOverheadLimit"'
        elif mem_level == 3:
            self._java_opts = r'declare -x JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=64m' \
                              r' -XX:MaxPermSize=256m -XX:-UseGCOverheadLimit"'
        elif mem_level == 4:
            self._java_opts = r'declare -x JAVA_OPTS="-Xms2048m -Xmx2048m -XX:PermSize=128m' \
                              r' -XX:MaxPermSize=256m -XX:-UseGCOverheadLimit"'
        else:
            self._java_opts = r'declare -x JAVA_OPTS="-Xms384m -Xmx384m -XX:PermSize=64m' \
                              r' -XX:MaxPermSize=256m -XX:-UseGCOverheadLimit"'

        self._http_port = str(port)
        self._debug_port = re.sub(r'(\d*)(\d)', r'\g<1>7', self._http_port)
        self._server_port = re.sub(r'(\d*)(\d)', r'\g<1>5', self._http_port)
        self._dubbo_port = re.sub(r'(\d*)(\d)', r'\g<1>8', self._http_port)

        # 描述一个tomcat所需的所有端口,这是一个共有属性
        self._ports = [self._http_port,
                       self._debug_port,
                       self._server_port,
                       self._dubbo_port]

        if self._nas_app_package_path == '':
            self._nas_app_package_path = '/mnt/winitRelease/latest.product/%s' % self._app_name

        self._nas_war_package_path = self._nas_app_package_path + self._sub_path + '/%s.war' % self._app_name

        self._war_name = re.sub("(.*/)(.*)", "\\2", self._nas_war_package_path)

        if war_exposed_name == '':
            self._war_path_name = re.sub("(.*)(\\.)(.*)", "\\1",
                                         self._war_name)
        else:
            self._war_path_name = re.sub("(.*)(\\.)(.*)", "\\1",
                                         war_exposed_name)

        self._war_exposed_path = self._app_home_path + '/' + self._war_path_name

        if app_config_home_path is None:
            self._app_config_home_path = self._config_home_path + '/' + self._zone_name + '/' + self._app_name
            self._app_config_home_path += '/src/main/resources'
        elif app_config_home_path == '#':
            self._app_config_home_path = self._config_home_path + '/' + self._zone_name + '/' + self._app_name
        else:
            self._app_config_home_path = app_config_home_path

        self._war_config_path = self._war_exposed_path + war_config_path

        self._war_lib_path = self._war_exposed_path + '/WEB-INF/lib'

        self._log_file_name = "%s/%s.log" % (
            BeetleConfig.APP_LOG_PATH, self._app_id)

        self._log_level = BeetleConfig.UCLOUD_APP_LOG_LEVEL

        self.timezone = timezone

    def set_runtime_param(self, nas_app_package, version = '', sub_path = ''):
        super(TomcatApp, self).set_runtime_param(
            nas_app_package = nas_app_package, version = version,
            sub_path = sub_path)
        self._nas_war_package_path = self._nas_app_package_path + self._sub_path + '/%s.war' % self._app_name

    # 验证应用
    def validate(self):
        pass

        # 安装应用war包到应用的tomcat webapps目录下.

    # 安装应用
    def install_app(self):

        # 1. 创建应用的tomcat容器. 配置好端口号等等.
        self._create_app_tomcat()

        # 2.解压war包, 并清理临时文件.
        self.download_and_install_package()

        # 3.替换配置文件.
        self._config_app()

        # 4.收尾工作, 将用户切换到vm的应用用户和用户组目录下.
        self.chmod()

        self.app_log('%s has been installed.' % self._app_id)

    # 启动应用
    def restart(self):
        # 先停后启动
        self.stop()
        _cmd = 'nohup %s/bin/startup.sh >/dev/null 2>&1 &' % self._container_home
        print self.run(command = _cmd)
        self.app_log(
            '%s has been restarted at %s.' % (self._app_id, self._http_port))

        time.sleep(3)

        self.app_log('Checking %s startup logging....' % self._app_id)

        _tail_log_cmd = 'tail -f %s' % self._log_file_name
        child = spawn(_tail_log_cmd)

        p_success = r"INFO: Server startup in \d* ms"
        p_exception = r".*Exception:.*"
        p_exception2 = r"SEVERE: Context \[/.*] startup failed due to previous errors"

        # expect刷日志会稍微有点延迟, 大概比实际日志的输出慢了半分钟左右.
        index = child.expect(
            pattern = [EOF, TIMEOUT, p_success, p_exception, p_exception2],
            timeout = BeetleConfig.UCLOUD_APP_STARTUP_TIMEOUT)

        if index == 1:
            raise Exception(
                '启动%s 超过%d秒, 请检查应用启动日志和dubbo服务, 确认应用是否正确启动.' % (
                    self._app_id, BeetleConfig.UCLOUD_APP_STARTUP_TIMEOUT))
        elif index > 2:

            time.sleep(5)
            # 暂时还不能停止, 因为很多应用循环依赖,启动一定会抛异常.
            # self.stop()

            raise Exception('在%s的启动日志中发现了Exception关键字, 可能启动失败, 也可能只是警告.'
                            ' 请检查应用启动日志和dubbo控制台, 确认应用是否启动正常.' % self._app_id)

        self.app_log(
            'App %s is startup completely. index=%d' % (self._app_id, index))

        # 用vm环境的应用的统一配置文件,覆盖发布包下的默认配置文件.

    def _config_app(self):

        self._update_config()

        if not os.path.isdir(self._app_config_home_path):
            msg = '没有找到配置文件, svn/winit2.0/config/UC 目录下没有该应用的配置文件?'
            raise Exception(msg)

        print '\cp -rf %s %s' % (
            self._app_config_home_path + '/*', self._war_config_path)

        _log, _result = self.run('/bin/bash -c "cp -rf %s/* %s"' % (
            self._app_config_home_path, self._war_config_path))

        self.app_log('%s change config file successfully.' % self._app_id)

        self.extend_config()

        self.patch_winit_common_jar()

    def patch_winit_common_jar(self):

        patch_path = BeetleConfig.APP_PATCH_PATH
        _war_lib_path = self._war_lib_path

        patches = FileUtil.findfiles(patch_path, ".*")

        for patch_file_name in patches:

            self.app_log('准备替换分页组件包：%s/%s' % (BeetleConfig.APP_PATCH_PATH, patch_file_name))
            import re
            file_prefix = re.sub("(.*?)(-\\d.*)", "\g<1>", patch_file_name)
            patch_partten = "(%s)(-\\d.*)" % file_prefix
            files = FileUtil.findfiles(_war_lib_path, patch_partten)
            for file_name in files:
                FileUtil.delete('%s/%s' % (_war_lib_path, file_name))
            self.app_log('替换分页组件包：%s/%s' % (_war_lib_path, patch_file_name))
            FileUtil.cp("%s/%s" % (patch_path, patch_file_name), "%s/%s" % (_war_lib_path, patch_file_name))

    def extend_config(self):
        if self._app_name == 'operation-portal':

            print '准备替换opc的自身配置文件 %s' % self._local_ip

            self.replace_config_content(
                file_path = self._app_home_path + '/operation-portal/WEB-INF/classes/environment.properties',
                pattern = r"(cas.server.host=http://)(.*)(:.*/cas\n)",
                repl = r"\g<1>%s\g<3>" % str(self._local_ip))

            self.replace_config_content(
                file_path = self._app_home_path + '/operation-portal/WEB-INF/classes/environment.properties',
                pattern = r"(cas.client.host=http://)(.*)(:)(\d*)(/operation-portal\n)",
                repl = r"\g<1>%s\g<3>%s\g<5>" % (
                    self._local_ip, self._http_port))

            self.replace_config_content(
                file_path = self._app_home_path + '/operation-portal/WEB-INF/classes/environment.properties',
                pattern = r"(winit.sc.host=http://)(.*)(:\d*/sc-api-web\n)",
                repl = r"\g<1>%s\g<3>" % self._local_ip)

        elif self._app_name == 'ims':

            _img_path = self._zone_home_path + '/work_dir/ims/label'

            self.run('mkdir -p %s' % _img_path)

            self.replace_config_content(
                file_path = self._app_home_path + '/ims/WEB-INF/classes/environment.properties',
                pattern = r"(ims.singleItem.label.pdf.path=)(.*)(/ims/label)",
                repl = r"\g<1>%s\g<3>" % _img_path)

        else:
            pass

        _logback_xml = "%s/logback.xml" % self._war_config_path

        if os.path.isfile(_logback_xml):
            _logback_xml_content = r'<?xml version="1.0" encoding="UTF-8"?>' + '\n' \
                                   + r'<configuration>' + '\n' \
                                   + r'    <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">' + '\n' \
                                   + r'      <file>%s</file>' % self._log_file_name + '\n' \
                                   + r'      <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">' + '\n' \
                                   + r'         <fileNamePattern>/tmp/logs/%s.%s.log</fileNamePattern>' % (
                                       self._app_id, '%i') + '\n' \
                                   + r'         <minIndex>1</minIndex>' + '\n' \
                                   + r'         <maxIndex>1</maxIndex>' + '\n' \
                                   + r'      </rollingPolicy>' + '\n' \
                                   + r'      <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">' + '\n' \
                                   + r'          <maxFileSize>30MB</maxFileSize>' + '\n' \
                                   + r'      </triggeringPolicy>' + '\n' \
                                   + r'      <encoder>' + '\n' \
                                   + r'          <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>' + '\n' \
                                   + r'      </encoder>' + '\n' \
                                   + r'    </appender>' + '\n' \
                                   + r'    <logger name="com.alibaba.dubbo.registry.zookeeper" level="ERROR"/>' + '\n' \
                                   + r'    <root level="%s">' % self._log_level + '\n' \
                                   + r'      <appender-ref ref="rollingFile" />' + '\n' \
                                   + r'    </root>' + '\n' \
                                   + r'</configuration>'

            with open(_logback_xml, 'w') as _f:
                _f.write(_logback_xml_content)

        self.replace_config_content(
            file_path = self._app_home_path + '/%s/WEB-INF/classes/application.properties' % self._app_name,
            pattern = r"(dubbo.protocol.port=)(\d*)",
            repl = r"\g<1>%s" % self._dubbo_port)

        self.replace_config_content(
            file_path = self._app_home_path + '/%s/WEB-INF/classes/environment.properties' % self._app_name,
            pattern = r"(dubbo.protocol.port=)(\d*)",
            repl = r"\g<1>%s" % self._dubbo_port)

    def download_and_install_package(self):

        self.run(command = '/bin/bash -c "cp -f %s %s" ' % (
            self._nas_war_package_path, self._app_home_path),
                 raise_on_error = True)

        self.run(
            command = 'unzip -qo %s' % self._app_home_path + '/' + self._war_name + ' -d %s' % self._war_exposed_path,
            raise_on_error = True)

        if not self._app_home_path == '':
            self.run('rm -f %s' % self._app_home_path + '/' + self._war_name)
        else:
            raise Exception('删除webapps下的临时war包失败:_app_home_path 为空')

        self.app_log('App pakcage has been downloaded.')

    # 创建当前应用的tomcat上下文路径
    def _create_app_tomcat(self):
        self.uninstall_app()

        # 1.创建tomcat的应用服务上下文文件夹.
        self.run('mkdir -p %s' % self._container_home);
        self.run('mkdir -p %s' % self._container_home + '/bin')
        self.run('mkdir -p %s' % self._container_home + '/logs')
        self.run('mkdir -p %s' % self._container_home + '/temp')
        self.run('mkdir -p %s' % self._container_home + '/conf')
        self.run('mkdir -p %s' % self._container_home + '/webapps')
        self.run('mkdir -p %s' % BeetleConfig.APP_LOG_PATH)

        self.run('cp -r %s %s' % (
            self._tomcat_template_home + '/conf', self._container_home))

        self.replace_config_content(
            file_path = self._container_home + '/conf/logging.properties',
            pattern = r"(1catalina.org.apache.juli.FileHandler.directory\s*=\s*)"
                      r"(\$\{catalina.base\}/logs)",
            repl = r"\g<1>%s" % BeetleConfig.APP_LOG_PATH)

        self.replace_config_content(
            file_path = self._container_home + '/conf/logging.properties',
            pattern = r"(1catalina.org.apache.juli.FileHandler.prefix\s*=\s*)(.*)",
            repl = r"\g<1>%s." % self._app_id)

        # 2.生成该上下文专用的启动文件. 按要求配置内存占用参数.
        file_startup_sh = r'#!/bin/sh' + '\n' + \
                          r'export CATALINA_BASE=%s' % self._container_home + '\n' + \
                          r'echo "Installing :%s' % self._app_name + '"\n' + \
                          self._java_opts + '\n' + \
                          r'declare -x CATALINA_OPTS="-server -Xdebug -Djava.awt.headless=true -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=%s"' % self._debug_port + '\n'
        # 特别工程需要添加新配置
        if self._app_name in BeetleConfig.ILS_PROJECT:
            file_startup_sh = r'%s' % file_startup_sh + '\n' + \
                              r'ILS_OPTS="-javaagent:$CATALINA_BASE/webapps/%s/WEB-INF/lib/ils-client-1.0.0-SNAPSHOT.jar"' % self._app_name + '\n' + \
                              r'JAVA_OPTS="$ILS_OPTS $JAVA_OPTS"' + '\n'

        file_startup_sh = r'%s' % file_startup_sh + \
                          r'%s/bin/startup.sh' % self._tomcat_template_home + '\n'

        with open(self._container_home + '/bin/startup.sh', 'w') as _f:
            _f.write(file_startup_sh)

        os.chmod(self._container_home + '/bin/startup.sh', 0777)

        # 3. 创建独立端口占用的server.xml
        with open(self._tomcat_template_home + '/conf/server.xml', 'r') as _f:
            _server_xml_content = _f.read()
            import re
            _server_xml_content = re.sub(r'(<Server\s*port\s*=\s*")(\d*)(")',
                                         r'\g<1>%s\g<3>' % self._server_port,
                                         _server_xml_content)
            _server_xml_content = re.sub(
                r'(<Connector\s*port\s*=\s*")(\d*)(")',
                r'\g<1>%s\g<3>' % self._http_port,
                _server_xml_content)

        with open(self._container_home + '/conf/server.xml', 'w') as _f:
            _f.write(_server_xml_content)


class UscheduleTomcatApp(TomcatApp):
    def __init__(self, app_id, app_name, zone_home_path, zone_alias, port,
                 nas_app_package_path = '',
                 sub_path = '',
                 tomcat_template_home = '/usr/local/soft/tomcat-7',
                 mem_level = 1,
                 container_home = '',
                 app_config_home_path = None,
                 war_exposed_name = '',
                 war_config_path = '/WEB-INF/classes',
                 timezone = ''):
        super(UscheduleTomcatApp, self).__init__(app_id = app_id,
                                                 app_name = app_name,
                                                 zone_home_path = zone_home_path,
                                                 zone_alias = zone_alias,
                                                 port = port,
                                                 sub_path = sub_path,
                                                 tomcat_template_home = tomcat_template_home,
                                                 nas_app_package_path = nas_app_package_path,
                                                 container_home = container_home,
                                                 app_config_home_path = app_config_home_path,
                                                 mem_level = mem_level,
                                                 war_exposed_name = war_exposed_name,
                                                 war_config_path = war_config_path,
                                                 timezone = timezone)
        self._uschedule_port = re.sub(r'(\d*)(\d)', r'\g<1>9', self._http_port)
        self._ports.append(self._uschedule_port)


class TomcatMultiWarApp(TomcatApp):
    def __init__(self, app_id, app_name, zone_home_path, zone_alias, port,
                 nas_app_package_path = '', container_home = '',
                 app_config_home_path = '', mem_level = 1, timezone = ''):

        super(TomcatMultiWarApp, self).__init__(app_id = app_id,
                                                app_name = app_name,
                                                zone_home_path = zone_home_path,
                                                zone_alias = zone_alias,
                                                port = port,
                                                nas_app_package_path = nas_app_package_path,
                                                container_home = container_home,
                                                app_config_home_path = app_config_home_path,
                                                mem_level = mem_level,
                                                timezone = timezone)

    def download_and_install_package(self):
        _log, _result = self.run(
            '/bin/bash -c "cp -rf %s %s" ' % (
                self._nas_app_package_path + self._sub_path + '/*',
                self._app_home_path))

        if not _result == 0:
            raise Exception('下载代码包失败, 是否指定了错误的路径?:' + _log)

        for i in os.listdir(self._app_home_path):

            _war_file_path = os.path.join(self._app_home_path, i)
            _war_exposed_name = re.sub("(.*)(\\..*)", "\\1", i)
            _war_exposed_path = os.path.join(self._app_home_path,
                                             _war_exposed_name)

            if os.path.isfile(_war_file_path):
                if not _war_file_path.endswith('.war'):
                    continue
                self.run(command = 'unzip -qo %s -d %s' % (
                    _war_file_path, _war_exposed_path), raise_on_error = True)

        if not self._app_home_path == '':
            self.run(
                r'/bin/bash -c "rm -f %s' % self._app_home_path + '/*.war"')
        else:
            raise Exception('删除webapps下的临时war包失败:_app_home_path 为空')

    # 用vm环境的应用的统一配置文件,覆盖发布包下的默认配置文件.
    def _config_app(self):

        for i in os.listdir(self._app_home_path):

            _sub_app_name = re.sub("(.*)(\\..*)", "\\1", i)
            _sub_app_config_home_path = self._config_home_path + '/' + self._zone_name + '/' + \
                                        self._app_name + '/' + _sub_app_name
            _war_config_path = self._app_home_path + '/' + _sub_app_name + '/WEB-INF/classes'

            if not os.path.isdir(_war_config_path):
                continue

            if not os.path.isdir(_sub_app_config_home_path):
                msg = 'Multi统一配置文件的svn上没有添加改环境?:' + _sub_app_config_home_path
                raise Exception(msg)

            _log, _result = self.run(
                '/bin/bash -c "cp -rf %s/* %s"' % (
                    _sub_app_config_home_path, _war_config_path))


class TomcatDepApp(TomcatMultiWarApp):
    def __init__(self, app_id, app_name, zone_home_path, zone_alias, port,
                 db_name, nas_app_package_path = '',
                 container_home = '',
                 app_config_home_path = '',
                 mem_level = 1,
                 timezone = ''):
        super(TomcatDepApp, self).__init__(app_id = app_id,
                                           app_name = app_name,
                                           zone_home_path = zone_home_path,
                                           zone_alias = zone_alias,
                                           port = port,
                                           nas_app_package_path = nas_app_package_path,
                                           container_home = container_home,
                                           app_config_home_path = app_config_home_path,
                                           mem_level = mem_level,
                                           timezone = timezone)
        self._db_name = db_name

    def _config_app(self):
        super(TomcatDepApp, self)._config_app()
        # sc 安装之后,还要在$container_home/conf/context.xml里补充一个数据源.
        _data_source = '<Context> \n\t' \
                       r'<Resource auth="Container" ' \
                       r'driverClassName="oracle.jdbc.driver.OracleDriver" ' \
                       r'maxActive="10" maxIdle="1" maxWait="2000" ' \
                       r'name="jdbc/DepDB" password="adempiere" ' \
                       r'type="javax.sql.DataSource" ' \
                       r'url="jdbc:oracle:thin:@127.0.0.1:1521:orcldb" username="%s" />' % self._db_name

        self.replace_config_content(
            file_path = self._container_home + '/conf/context.xml',
            pattern = r"<Context>",
            repl = _data_source)


class TomcatOpenApiApp(TomcatApp):
    def _config_app(self):
        super(TomcatOpenApiApp, self)._config_app()
        # openapi已经不需要ad
        pass
        # sc 安装之后,还要在$container_home/conf/context.xml里补充一个数据源.
        # _context_source = r'\g<1>\n        <Context docBase="openapi" path="/ADInterface" reloadable="true" />'
        #
        # self.replace_config_content(
        #     file_path=self._container_home + '/conf/server.xml',
        #     pattern=r"(.*autoDeploy=\"true\">\n)",
        #     repl=_context_source)


class TomcatScApp(ContainerApp):
    def validate(self):
        pass

    def __init__(self, app_id, zone_home_path, zone_alias, port,
                 nas_app_package_path = '/mnt/winitRelease/latest.product/sc',
                 db_name = 'sc', mem_level = 1, timezone = ''):
        super(TomcatScApp, self).__init__(app_id = app_id, app_name = 'sc',
                                          zone_home_path = zone_home_path,
                                          zone_alias = zone_alias, port = port,
                                          container_home = '',
                                          nas_app_package_path = nas_app_package_path,
                                          app_config_home_path = '')

        self._sc_port = str(port)

        self._db_name = db_name

        _subport = re.sub(r'(\d*)(\d{2})', r'\g<1>', self._sc_port)
        _subport = int(_subport) + 1
        self._sc_manager_port = re.sub(r'(\d*)(\d{2})', r'%s\g<2>' % _subport,
                                       self._sc_port)

        # self.app_log('_sc_port: %s _sc_manage_port: %s' % (self._sc_port, self._sc_manager_port))
        self._mem_level = mem_level

        self._sc_container_home = zone_home_path + '/tomcat_sc'
        self._sc_manage_container_home = zone_home_path + '/tomcat_sc-manage'

        self._sc_tomcat = TomcatMultiWarApp(
            app_id = app_id,
            app_name = 'sc',
            zone_home_path = zone_home_path,
            zone_alias = zone_alias,
            port = self._sc_port,
            nas_app_package_path = nas_app_package_path + '/sc',
            container_home = self._sc_container_home,
            app_config_home_path = '#',
            mem_level = self._mem_level,
            timezone = timezone)

        self._sc_manager_tomcat = TomcatApp(
            app_id = app_id,
            app_name = 'sc-manage-web',
            zone_home_path = zone_home_path,
            zone_alias = zone_alias,
            port = self._sc_manager_port,
            nas_app_package_path = nas_app_package_path + '/sc-manage',
            container_home = self._sc_manage_container_home,
            app_config_home_path = '/usr/local/config/%s/%s' % (
                self._zone_name, 'sc/sc-manage-web'),
            mem_level = self._mem_level,
            timezone = timezone)

        self.ports = self._sc_tomcat.get_ports() + self._sc_manager_tomcat.get_ports()

    # 安装应用
    def install_app(self):
        self._sc_tomcat.install_app()
        self._sc_manager_tomcat.install_app()

        self._config_app()

        self.app_log('sc has been started at %s' % self._sc_port)

        self.app_log(
            'sc-manager has been started at %s' % self._sc_manager_port)

    # 重启应用
    def restart(self):
        self._sc_tomcat.restart()
        self._sc_manager_tomcat.restart()

    def stop(self):
        self._sc_tomcat.stop()
        self._sc_manager_tomcat.stop()

    def is_started(self, accurately = False):
        _is_sc_started = self._sc_tomcat.is_started(accurately = accurately)
        # _is_sc_manager_started = self._sc_manager_tomcat.is_started(
        #     accurately=accurately)

        # return _is_sc_started and _is_sc_manager_started
        return _is_sc_started

    def uninstall_app(self):
        self._sc_tomcat.uninstall_app()
        self._sc_manager_tomcat.uninstall_app()

    def _config_app(self):
        # sc 安装之后,还要在$container_home/conf/context.xml里补充一个数据源.
        _data_source = '<Context> \n\t' \
                       r'<Resource auth="Container" ' \
                       r'driverClassName="com.mysql.jdbc.Driver" ' \
                       r'maxActive="30" maxIdle="3" maxWait="2000" ' \
                       r'name="jdbc/SCDB" password="winit2015" ' \
                       r'type="javax.sql.DataSource" ' \
                       r'url="jdbc:mysql://127.0.0.1:3306/%s" username="root" />' % self._db_name

        with open(self._sc_container_home + '/conf/context.xml', 'r') as _f:
            _context_xml_content = _f.read()
            _context_xml_content = re.sub(r'<Context>', _data_source,
                                          _context_xml_content)

        with open(self._sc_container_home + '/conf/context.xml', 'w') as _f:
            _f.write(_context_xml_content)

        with open(self._sc_manage_container_home + '/conf/context.xml',
                  'w') as _f:
            _f.write(_context_xml_content)

        _sc_application_xml = self._sc_container_home + '/webapps/sc-api-web/WEB-INF/classes/conf/' \
                                                        'applicationContext.xml'
        with open(_sc_application_xml, 'r') as _f:
            _sc_application_xml_content = _f.read()

        with open(_sc_application_xml, 'w') as _f:
            _sc_application_xml_content = re.sub(r'(.*<bean\s*id="log.*)',
                                                 '<!--\g<1>-->',
                                                 _sc_application_xml_content)
            _f.write(_sc_application_xml_content)

        _sc_manage_securtiy_file = self._sc_manage_container_home + '/webapps/sc-manage-web/' \
                                                                    'WEB-INF/classes/conf/spring.security.properties'

        with open(_sc_manage_securtiy_file, 'r') as _f:
            _sc_manage_securtiy_properties = _f.read()
            _sc_manage_securtiy_properties = re.sub(
                r'(http://)(.*)(:)(\d*)(/cas|/sc-api-web)',
                r'\g<1>%s\g<3>%s\g<5>' % (self._local_ip, self._sc_port),
                _sc_manage_securtiy_properties)
            _sc_manage_securtiy_properties = re.sub(
                r'(http://)(.*)(:)(\d*)(/sc-manage-web)',
                r'\g<1>%s\g<3>%s\g<5>' % (
                    self._local_ip, self._sc_manager_port),
                _sc_manage_securtiy_properties)
        with open(_sc_manage_securtiy_file, 'w') as _f:
            _f.write(_sc_manage_securtiy_properties)

        self.app_log('%s has been stoped.' % self._app_id)
